package com.macro.mall.common.log;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import org.springframework.core.env.Environment;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * 统一日志工具类
 * 提供统一格式的日志记录功能
 */
public class UnifiedLogUtil {
    
    private static final Logger logger = LoggerFactory.getLogger(UnifiedLogUtil.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static final Marker UNIFIED_LOG_MARKER = MarkerFactory.getMarker("UNIFIED_LOG");
    
    // 静态变量，用于存储环境信息
    private static String ip;
    private static String service;
    private static String env;
    private static String group;
    
    static {
        try {
            ip = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            ip = "unknown";
        }
        // 默认值，实际使用时可以通过Spring注入Environment来获取
        env = "dev";
        group = "default";
    }
    
    /**
     * 设置环境信息
     * @param environment Spring环境变量
     * @param serviceName 服务名
     */
    public static void setEnvironment(Environment environment, String serviceName) {
        if (environment != null) {
            env = environment.getProperty("spring.profiles.active", "dev");
        }
        service = serviceName;
    }
    
    /**
     * 记录统一格式的业务日志
     * @param type 类型
     * @param className 类名
     * @param method 方法名
     * @param request 请求参数
     * @param response 响应结果
     * @param executeTime 执行时间
     * @param exception 异常信息
     */
    public static void log(String type, String className, String method, 
                          Object request, Object response, Long executeTime, Throwable exception) {
        com.macro.mall.common.log.UnifiedLog unifiedLog = new com.macro.mall.common.log.UnifiedLog();
        unifiedLog.setIp(ip);
        unifiedLog.setGroup(group);
        unifiedLog.setEnv(env);
        unifiedLog.setService(service);
        unifiedLog.setType(type);
        unifiedLog.setClassName(className);
        unifiedLog.setMethod(method);
        unifiedLog.setExecuteTime(executeTime);
        
        // 获取traceId
        String traceId = getTraceId();
        unifiedLog.setTraceId(traceId);
        
        // 设置请求和响应
        if (request != null) {
            unifiedLog.setRequest(toJsonString(request));
        }
        if (response != null) {
            unifiedLog.setResponse(toJsonString(response));
        }
        
        // 设置异常信息
        if (exception != null) {
            unifiedLog.setException(exception.getClass().getName() + ": " + exception.getMessage());
        }
        
        // 输出日志
        logger.info(UNIFIED_LOG_MARKER, toJsonString(unifiedLog));
    }
    
    /**
     * 记录统一格式的业务日志（简化版）
     * @param type 类型
     * @param className 类名
     * @param method 方法名
     * @param request 请求参数
     * @param response 响应结果
     */
    public static void log(String type, String className, String method, Object request, Object response) {
        log(type, className, method, request, response, null, null);
    }
    
    /**
     * 记录统一格式的业务日志（带执行时间）
     * @param type 类型
     * @param className 类名
     * @param method 方法名
     * @param request 请求参数
     * @param response 响应结果
     * @param executeTime 执行时间
     */
    public static void log(String type, String className, String method, 
                          Object request, Object response, Long executeTime) {
        log(type, className, method, request, response, executeTime, null);
    }
    
    /**
     * 获取traceId
     * @return traceId
     */
    private static String getTraceId() {
        // 这里可以从MDC中获取traceId
        // 实际实现时需要根据项目中的MDC实现来获取
        String traceId = org.slf4j.MDC.get("traceId");
        if (traceId == null) {
            traceId = "traceId-placeholder";
        }
        return traceId;
    }
    
    /**
     * 将对象转换为JSON字符串
     * @param obj 对象
     * @return JSON字符串
     */
    private static String toJsonString(Object obj) {
        if (obj == null) {
            return null;
        }
        
        if (obj instanceof String) {
            return (String) obj;
        }
        
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            logger.warn("Failed to convert object to JSON string", e);
            return obj.toString();
        }
    }
}